package ca.uwindsor.cs.deepweb.estimation.method.border;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Random;

import ca.uwindsor.cs.deepweb.utility.StandardDeviation;

public class TermWeightEstimatorThread extends Thread {

	private ArrayList<TermCell<Float, Integer>> list;

	private String[] terms;

	private String[] querypool;

	private long sumdf;

	private int numberofrandomterms;

	private float meanweight;

	/**
	 * @param numberofrandomterms
	 * @param numberofruns
	 */
	public TermWeightEstimatorThread() {
		list = new ArrayList<TermCell<Float, Integer>>();
		init();
	}

	protected void init() {
		sumdf = 0;
		numberofrandomterms = 0;
		meanweight = 0;
	}

	public void load(String file) throws IOException {
		InputStreamReader reader = null;
		BufferedReader bufferedreader_in;
		String string_line = new String();
		String[] temp;
		reader = new InputStreamReader(new FileInputStream(file));
		bufferedreader_in = new BufferedReader(reader);
		string_line = bufferedreader_in.readLine();
		while (string_line != null) {
			if (!string_line.equals("")) {
				temp = string_line.split("\t");
				TermCell<Float, Integer> cell;
				if (temp.length == 3) {
					cell = new TermCell<Float, Integer>(temp[0], Float
							.parseFloat(temp[1]), Integer.parseInt(temp[2]));
				} else {
					cell = new TermCell<Float, Integer>(temp[0], Float
							.parseFloat(temp[1]), 0);
				}
				list.add(cell);
			}
			string_line = bufferedreader_in.readLine();
		}
		reader.close();
	}

	public void setNumberofRandomTerms(int quatity) {
		init();
		numberofrandomterms = quatity;
	}

	public void run() {
		if (numberofrandomterms != 0) {
			meanweight = 0;
			terms = new String[numberofrandomterms];
			float mean = 0.0f;
			sumdf = 0;
			Random r = new Random();
			int size = list.size();
			short i;
			TermCell<Float, Integer> tc;
			if (size < numberofrandomterms) {
				numberofrandomterms = (short) size;
			}
			for (i = 0; i < numberofrandomterms; i++) {
				tc = list.get(r.nextInt(size));
				mean = mean + tc.getValue().floatValue();
				terms[i] = tc.getTerm();
				sumdf = sumdf + tc.getDF();
			}
			mean = mean / numberofrandomterms;
			meanweight = mean;
		}
	}

	/**
	 * @deprecated added threading support, set the number of random terms using
	 *             setNumberofRandomTerms(int) and invoke start() instead,
	 * */
	public float getMeanWeight(int numberofrandomterms) {
		terms = new String[numberofrandomterms];
		float mean = 0.0f;
		sumdf = 0;
		Random r = new Random();
		int size = list.size();
		short i;
		TermCell<Float, Integer> tc;
		if (size < numberofrandomterms) {
			numberofrandomterms = (short) size;
		}
		for (i = 0; i < numberofrandomterms; i++) {
			tc = list.get(r.nextInt(size));
			mean = mean + tc.getValue().floatValue();
			terms[i] = tc.getTerm();
			sumdf = sumdf + tc.getDF();
		}
		mean = mean / numberofrandomterms;
		return mean;
	}

	public String[] getTerms() {
		return terms;
	}

	public int getQueryPoolSize() {
		return list.size();
	}

	public long getDFSum() {
		return sumdf;
	}

	public String[] getQueryPool() {
		querypool = new String[list.size()];
		for (int i = 0; i < querypool.length; i++) {
			querypool[i] = list.get(i).getTerm();
		}
		return querypool;
	}

	public float getMeanWeight() {
		return meanweight;
	}

	public int getEstimatedSize() {
		return (int) (meanweight * querypool.length);
	}
	
	public ArrayList<TermCell<Float, Integer>> getWeightDFList(){
		return this.list;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		args = new String[1];
		args[0] = "D:\\Research\\estimation\\Result\\Reuters\\newmethod\\Retuers_random40000_500_1500_term_weight_df_only.txt";
		short numberofrandomterms = 10;
		short run = 100;
		short i, j, k;
		float mean = 0;
		long meandfsum = 0;
		TermWeightEstimatorThread e = new TermWeightEstimatorThread();
		StringBuilder result = new StringBuilder();
		try {
			e.load(args[0]);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			System.exit(0);
		}
		double[] temp;
		for (i = 100; i <= numberofrandomterms; i += 100) {
			for (j = 10; j <= run; j += 10) {
				temp = new double[j];
				for (k = 0; k < j; k++) {
					temp[k] = e.getMeanWeight(i);
					mean = mean + e.getMeanWeight(i);
					meandfsum = meandfsum + e.getDFSum();
				}
				mean = mean / j;
				result.append(i);
				result.append("\t");
				result.append(j);
				result.append("\t");
				result.append(mean);
				result.append("\t");
				result.append(StandardDeviation.sdFast(temp));
				result.append("\t");
				result.append(meandfsum);
				result.append("\n");
				System.out.print(result);
				result.delete(0, result.length());
			}
		}

	}

}
